/**
 * 三数之和
 * 给你一个包含n个整数的数组nums，判断nums中是否存在三个元素a，b，c ，使得a + b + c = 0。
 * 请你找出所有满足条件且不重复的三元组。
 * 注意：答案中不可以包含重复的三元组。
 * 
 * 每次指针移动一次位置，就计算一下两个指针指向数字之和加上固定的那个数之后，是否等于 0。
 * 如果是，那么我们就得到了一个目标组合；否则，分两种情况来看：
 * 相加之和大于 0，说明右侧的数偏大了，右指针左移
 * 相加之和小于 0，说明左侧的数偏小了，左指针右移
 * @param {*} nums 
 */
function threeSum(nums = [], target) {
    let len = nums.length;
    let list = [];
    nums.sort((a, b) => a - b);
    console.log(nums)
    for (let i = 0; i < len - 2; i++) {
        // i是固定某个值
        let left = i + 1; // 左指针
        let right = len - 1; // 右指针
        // 如果有重复值，就直接继续，
        if (i > 0 && nums[i] === nums[i - 1]) {
            continue;
        }
        /**
         * 注意这里不能是下面的判断，比如说[-4,-4,3,2],
         * 如果使用下面的条件，那么相当于忽略了第一个-4和第二个-4相加的情况，会导致少了计算
         * if (i > 0 && nums[i] === nums[i + 1]) {
                continue;
            }

         */
        while (left < right) {
            // console.log(i, left, right, nums[i], nums[left], nums[right])
            if (nums[i] + nums[left] + nums[right] === target) {
                list.push([nums[i], nums[left], nums[right]]);
                left++;
                right--;
                while (left < right && nums[left] === [left + 1]) {
                    left++;
                }
                while (left < right && nums[right] === [right - 1]) {
                    right--;
                }
            } else if (nums[i] + nums[left] + nums[right] < target) { // 小于目标值的话
                left++;
                while (left < right && nums[left] === [left - 1]) {
                    left--;
                }
            } else {
                right--;
                while (left < right && nums[right] === [right - 1]) {
                    right--;
                }

            }
        }
    }
    return list;
}

console.log(threeSum([-1, 0, 1, 2, -1, -4], 0));